#ifndef SYSTEMMONITOR_H
#define SYSTEMMONITOR_H

#include <QObject>
#include <QTimer>
#include <QThread>
#include <QMutex>

#define SYSTEMMONITOR HIM::SystemMonitor::getInstance()

namespace HIM {

enum DATAINDEX
{
    toolButton_deviceStatus = 1,

    label_alarm_plcConn,
    label_alarm_ethrrcatConn,
    label_alarm_rtcConn ,
    label_alarm_mongoDBConn,

    label_alarm_fan,
    label_alarm_watercooling,
    label_alarm_cabinDoor,
    label_alarm_O2,
    label_alarm_cabinPressure,

    label_alarm_laser,
    label_alarm_servoMan,
    label_alarm_servoFeed,
    label_alarm_servoPow,
    label_alarm_EnvTemp,

    label_statusairsupplyvalve,
    label_statusCabinPressure,
    label_statusWashingvalvePressure,
    label_statusO2,
    label_statsusAirO2,
    label_statusBaseTemperature,
    label_statusEnvTemperature,
    label_cp_3,
    label_statusSpeedFan,
    label_cp_2,
    label_cp_7,
    label_cp_8,
    label_cp_9,
    label_loopCleanStatus,

    label_laserStatus,
    label_statusServoPowder,
    label_statusServoFeed,
    label_statusServoMan,

    pushButton_servoManufactureEnable,
    pushButton_servoFeedEnable,
    pushButton_servoPowderEnable,

};

typedef enum{
    SYS_ERR,
    SYS_NORMAL,
    SYS_PRINT,
} SysStatus;

class SystemMonitorThread : public QThread
{
    Q_OBJECT
public:
    explicit SystemMonitorThread(){};
    ~ SystemMonitorThread(){};
    virtual void run() override;

public slots:
    void on_timeout();
};

class SystemMonitor : public QObject
{
    Q_OBJECT
public:
    static SystemMonitor& getInstance(){
        static SystemMonitor instance;
        return instance;
    };

    bool getNetworkCordInfo(
            std::vector<std::pair<std::string,std::string>>& NetworkInfos);

    void initSyncMap();
    void connectAll();
    void doDataSync();

    bool laserSafeCheck();

    void loadAllConfig();
    void applySysParas();
    void applyServoParas();
    void applyLaserParas();

    double getFeedPos(){
        return feedPos.load();
    }

    double getManPos(){
        return manPos.load();
    }

    double getPowPos(){
        return powPos.load();
    }

    bool getFeedInPlace(){
        return feedInPlace.load();
    }

    bool getManInPlace(){
        return manInPlace.load();
    }

    bool getPowInPlace(){
        return powInPlace.load();
    }

    SysStatus getSysStatus(){
        return sysStatus;
    };

    bool getServosEnable();

private:
    SystemMonitor();
    ~SystemMonitor();
    SystemMonitor(const SystemMonitor&) = delete;
    SystemMonitor& operator=(const SystemMonitor&) = delete;

    bool networkCardConnect();
    void plcConnect();
    void rtcConnect();
    void dbConnect();

    void networkCardDisonnect();
    void plcDisconnect();
    void rtcDisconnect();
    void dbDisconnect();

signals:
    void dataSynchronous(QMap<int,float> syncMap);

public slots:  
    void on_initApp();


private:
    SystemMonitorThread *systemMonitorThread;
    SysStatus sysStatus{SYS_ERR};

    std::atomic<double> feedPos{0.0};
    std::atomic<double> manPos{0.0};
    std::atomic<double> powPos{0.0};

    std::atomic<bool> feedInPlace{false};
    std::atomic<bool> manInPlace{false};
    std::atomic<bool> powInPlace{false};
};
}
#endif // SYSTEMMONITOR_H
